#include "../include/disks.h"
#include "../include/ptrlist.h"
#include "../include/disk.h"
#include "../include/state.h" 
#include "../include/macro_report.h"
#include "../include/macro_constant.h"
#include "../include/winapi.h"
#include "../include/fs.h"
Disks::Disks()
{
	disk_array=getEveryThing();
	setWindowsFsName();
}
Disks* Disks::disks_ptr=NULL;
PtrArray<Disk> Disks::getEveryThing()
{
	HANDLE hfile=NULL;
	char disk_str[21]="\\\\.\\PhysicalDrive";
	PtrList<Disk> disks(2,false);
	for(uint32 i=0;i<=DISK_COUNT;i++)
	{
		if(i<10)
		{
			disk_str[17]=i+0x30;
			disk_str[17+1]=0;
		}
		else if(i>=10&&i<100)
		{
			disk_str[17]=i/10+0x30;
			disk_str[17+1]=(i%10)+0x30;
			disk_str[17+2]=0;
		}
		else if(i>=100&&i<1000)
		{
			disk_str[17]=i/100+0x30;
			disk_str[17+1]=((i%100)/10)+0x30;
			disk_str[17+2]=((i%100)%10)+0x30;
			disk_str[17+3]=0;
		}
		hfile=WinAPI::openDisk(disk_str);
		if(hfile==INVALID_HANDLE_VALUE)
		{
			uint32 error_code=GetLastError();
			if(error_code!=ERROR_FILE_NOT_FOUND)
			{
				State::state().reportError(ERROR_TYPE_OPENDISK,error_code);
				return PtrArray<Disk>();
			}
		}
		else
		{
			Disk* disk=NULL;
			try
			{
				disk=new Disk(hfile,i);
			}
			catch(...)
			{
				continue;
			}
			disks.push(disk);
		}
	}
	PtrArray<Disk> tmp(disks.size);
	disks.copyTo(tmp);
	return tmp;
}
void Disks::setWindowsFsName()
{
	uint32 win_fs_count=WinAPI::getWindowsFsCount();
	uint32 root_paths_size=win_fs_count*8;
	uint16* root_paths=new uint16[root_paths_size+1];
	WinAPI::getWindowsFsStr(root_paths,root_paths_size+1);
	STORAGE_DEVICE_NUMBER info;
	for(uint32 i=0;i<root_paths_size;i+=4)
	{
		uint32 drive_type=WinAPI::getDriveType(root_paths+i);
		if(drive_type==DRIVE_REMOVABLE||drive_type==DRIVE_FIXED)
		{
			WinAPI::getWindowsFsIndex(root_paths+i,info);
			for(uint32 j=0;j<disk_array.size();j++)
				if(disk_array[j].winDiskIndex()==info.DeviceNumber)
				{
					if(info.PartitionNumber>disk_array[j].fsCount())
						break;
					disk_array[j][info.PartitionNumber-1].setFsName(WinAPI::getWindowsFsName(root_paths+i));
					break;
				}
		}
	}
	delete[] root_paths;
}

